home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / MWCC03.ZIP / WINMENU.ZIP / WINMENU.PAS < prev    next >
Pascal/Delphi Source File  |  1993-08-18  |  36KB  |  1,089 lines

  1. {**********************************************************************}
  2. {*                                                                    *}
  3. {*          Microworks Sample Application                                        *}
  4. {*                                                                    *}
  5. {*         for Borland Pascal v7.0 and Turbo Pascal for Windows v1.5           *}
  6. {*                                                                    *}
  7. {*     Copyright 1992-93 Jeff Franks (Microworks) Sydney, Australia.  *}
  8. {*                                                                    *}
  9. {*         You are free to use, modify, reproduce and distribute the      *}
  10. {*         Sample Files (and/or any modified version) in any way you      *}
  11. {*         find useful.                                                                *}
  12. {*                                                                    *}
  13. {**********************************************************************}
  14.  
  15. {*** Introduction
  16.  
  17.     Application := Winmenu 3D Ownerdraw Menu Demonstration
  18.  
  19.     Files       := Winmenu.exe, Winmenu.pas, Winmenu.res
  20.  
  21.     Requires    := MObjects, MMsgBox and MWCC.dll
  22.  
  23.     Purpose     := Winmenu shows you how to,
  24.  
  25.                                  1. Set up a 3D Menu bar using TMWCCButtons and popup menus.
  26.  
  27.                                  2. Use CreatePopupMenu and TrackPopupMenu.
  28.  
  29.                                  3. Create ownerdraw popup menus using wm_DrawItem and wm_MenuChar.
  30.  
  31.                                  4. Use the wh_Keyboard Hook from HotKey1 example.
  32.  
  33.                                  4. Use some of the objects and custom controls
  34.                                         in the MWCC unit and library.
  35.  
  36.                                  5. Use the SFXMsgBox and MWCCMsgBox functions instead of
  37.                                         the Windows API MessageBox function.
  38.  
  39.     Tabs        := 2
  40.  
  41.     Screen      := 800 * 600
  42.  
  43.     Date        := August 1993.
  44.  
  45. {*** About TMWCCWindow
  46.  
  47.     The TMWCCWindow object works differently depending on how you set it up. One of the main
  48.     things you should be aware of is the way it uses normal menus and ws_VScroll and ws_HScroll
  49.     scroll bars. This is only of concern if you give your window an SFX style frame by setting
  50.     SFXFrame := True in the constructor.
  51.  
  52.     The TMWCCWindow and TMWCCDlgWindow objects intercept the wm_NCPaint message to paint their
  53.     frame and title bar. After painting, if you pass the message along to DefWndProc it then
  54.     draws the normal frame as well. What you would see when you ran the program would be a
  55.     quick flash of normal frame colour before my NCPaint routine paints the SFX style frame.
  56.     It is reasonably fast and most noticeable when you resize the window. This is how the
  57.     Microsoft Ctl3d.dll paints its frames. It just paints over the existing colours.
  58.  
  59.     Well, I wasn't satisfied with that. I don't like seeing flashing colours. The
  60.     only alternative was to draw the non-client area myself(What a pain!!!). It was easy to
  61.     draw the frame and the title    bar but I couldn't get the menu bar or scroll bars to
  62.     display properly. If your window doesn't use menu's or scroll bars then its Ok.
  63.     You don't pass the wm_NCPaint message onto DefWndProc, you draw the frame yourself and you
  64.     don't see any flashing colours. Unfortunaletly, most windows need atleast a menu and
  65.     often a scroll bar.
  66.  
  67.     My solution was to optionally pass wm_NCPaint along to DefWndProc. If the Attr.Style
  68.     includes ws_VScroll or ws_HScroll or if your window has a class menu then wm_NCPaint
  69.     is passed to DefWndProc and the non-client area is drawn normally. If you use an
  70.     SFX style frame it just gets drawn over the top. When your window doesn't use a class
  71.     menu and/or doesn't have ws_VScroll or ws_HScroll in its Attr.Style field then the wm_NCPaint
  72.     message is not get passed along to DefWndProc.
  73.  
  74.     (This is a the way SFX objects work (TSFXWindow etc) except they don't pass wm_NCPaint
  75.     on at all. Thats why you can't use menus etc with them. If you add a menu or scroll bar
  76.     the object destroys them before displaying the window/dialog.)
  77.  
  78.     I think its important to try and give your program classy interface. Thats where 'Winmenu'
  79.     comes in. It shows you an alternative way to institute a (3D) menu bar using buttons and
  80.     popup menus. It also shows you whats needed to make the separate buttons and menus function
  81.     together as a single unit like a normal menu bar. And there's more! It matches the
  82.     design on the window, you don't see any colour flashes around the frame and it looks great!
  83.  
  84. {*** About Winmenu
  85.  
  86.     Winmenu shows you one way to set up a 3D menu bar with ownerdraw menus. I'm still working on
  87.     refining the way the menus work so expect some improvements in future.
  88.  
  89.     Drawing ownerdraw menus is much the same as drawing ownerdraw list boxes. In this example
  90.     I didn't worry about adding bitmap glyphs for each menu item but you can easily add them
  91.     in same way you would    to ownerdraw list box items (see Wintask).
  92.  
  93.     I played around with several ideas for ownerdraw menus until I came up with the menus in
  94.     Winmenu. Each menu item is drawn as a separate 3D block and uses its own 'checked' bitmap
  95.     when checked (see Object Viewer). I didn't bother about menu separators. If you want
  96.     separators you'll have to add them to the wm_DrawItem method yourself.    After looking at
  97.     the way OS/2 draws its menus (and other programs) I felt it looked better to have the
  98.     highlighted menu item a different colour. The default highlight text and background only
  99.     look good with a bold font and I didn't want a bold font. If I use these menus as is, I will
  100.     let the user select the highlight background and highlight text color as an option.
  101.  
  102.     I tried making the menu items look like buttons but it didn't look right because regular
  103.     menus don't operate like buttons.
  104.  
  105.     The wm_MenuChar method method handles the menu item's keyboard mnemonic. This method is very
  106.     important when you draw ownerdraw menus.
  107.  
  108.     The other methods like wm_Hotkey, wm_ResetMenus and the TMenuButtons are all designed to
  109.     make the 3D menus work more like regular menus.
  110.  
  111.     I hope you find this example useful.
  112.  
  113.     Jeff...
  114.  
  115. ***}
  116.  
  117. program WinMenu;
  118.  
  119. {$R WinMenu.res}
  120.  
  121. uses WinTypes, WinProcs, WinDos, Win31, Strings, MObjects, MMsgBox,
  122.          {$IFDEF Ver15}
  123.              WObjects;
  124.          {$ELSE}
  125.              Objects, OWindows, ODialogs;
  126.          {$ENDIF}
  127.  
  128. const
  129.  
  130.     {*** Menu Button ID's ***}
  131.     idm_But1                                 = 201;
  132.     idm_But2                                 = 202;
  133.     idm_But3                                 = 203;
  134.     idm_But4                                 = 204;
  135.     idm_But5                                 = 205;
  136.  
  137.     {*** Window Static ID ***}
  138.     idw_Stat1                                = 401;
  139.  
  140.     {*** About Dialog ID's ***}
  141.     idd_OkBut                    = 402;
  142.  
  143.     {*** Menu Item ID's ***}
  144.     idm_Item1                                = 701;
  145.     idm_Item2                                = 702;
  146.     idm_Item3                    = 703;
  147.     idm_Item4                    = 704;
  148.     idm_About                    = 705;
  149.  
  150.     {*** Miscellaneous ID's ***}
  151.     pToHotKeyHookProc : TFarProc = nil;
  152.     wm_HotKey                    = wm_User + 76;
  153.     wm_ResetMenus                = wm_User + 202;
  154.     AppName : PChar              = 'WinMenu';
  155.  
  156. type
  157.  
  158.     PAboutDialog = ^TAboutDialog;
  159.     TAboutDialog = object(TMWCCDialog)
  160.         {***
  161.  
  162.             TMWCCBmpButton is a BWCC style bitmap button object. TMWCCStatic is a static object
  163.             that displays either raised, recessed or normal static controls. WMDrawItem is required
  164.             to draw the TMWCCBmpButton ownerdraw button object.
  165.  
  166.         ***}
  167.         OkBut    : PMWCCBmpButton;
  168.         ST1, ST2 : PMWCCStatic;
  169.         constructor Init (AParent: PWindowsObject; AName, ABmp: PChar);
  170.         procedure SetUpWindow; virtual;
  171.         procedure WMDrawItem (var Msg: TMessage); virtual wm_First + wm_DrawItem;
  172.     end;
  173.  
  174.     PMenuButton = ^TMenuButton;
  175.     TMenuButton = object(TMWCCButton)
  176.         {***
  177.  
  178.             The TMWCCButton object draws a button displaying either Text or a single Bitmap.
  179.             MWCCButtons don't support the 'default' field. That's so you can draw recessed (etc)
  180.             buttons without thick black borders spoiling the 3D effect.
  181.  
  182.             TMenuButton overrides the default TMWCCButton font and creates a larger font suitable
  183.             for menus. It also sets up the wm_MouseMove mehtod to reset all the menus.
  184.  
  185.         ***}
  186.         MenuFont : HFont;
  187.         destructor Done; virtual;
  188.         procedure SetupWindow; virtual;
  189.         procedure WMMouseMove (var Msg: TMessage); virtual wm_First + wm_MouseM